package cn.xawl.interview.thread;

/**
 * @author lh
 * @date 2020/08/23 22:11:16
 *
 *
 * DCL（Double Check Lock）机制的单例模式
 * 由于对象的初始化过程在伪代码中分为3步，分配空间–>初始化对象–>设置变量指向内存地址。
 * 这三个步骤不存在依赖关系，会出现指令重排。当步骤2和步骤3交换后，出现了未初始化完成对象的情况下一个线程认为该对象已经初始化完成，从而取得一个空的地址值。
 *
 **/
public class Singleton {
    //使用volatile，new对象的时候就不会发生指令重排而导致获取到一个空的对象
    private volatile static Singleton instance = null;

    private Singleton() {
        System.out.println(Thread.currentThread().getName() + "\t使用构造方法创建对象");
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        for (int i = 1; i <= 10000; i++) {
            new Thread(Singleton::getInstance, String.valueOf(i)).start();
        }
    }


}
